
/*-------------------------------------------------------------------------

***************** Modification History ***********************************
   @doc
   @module batchfun.c - Functions for Batch File Maintenance |
   @end

$Log: /SoftPay/SPK2SIM/Source/Batch/batchfun.c $
**************************************************************************

   Copyright (C) 1999 by VeriFone, Inc.

   All rights reserved.  No part of this software may be reproduced,
   transmitted, transcribed, stored in a retrieval system, or translated
   into any language or computer language, in any form or by any means,
   electronic, mechanical, magnetic, optical, chemical, manual or otherwise,
   without the prior written permission of VeriFone, Inc.

---------------------------------------------------------------------------*/

#include <project.h>

#ifdef BATCH_DEFINED

#define BATCHFUN_C

#include <aclconio.h>
#include <stdlib.h>
#include <stdio.h>
#include <ascii.h>
#include <errno.h>
//#include "\predator\verixsdk\include\errno.h"
#include <svc.h>
#include <dbmgr.h>
#include <string.h>
#include <message.h>
#include <aclstr.h>
#include <aclutil.h>
#include <VarRec.h>

/** /#define DEBUG_BATCHFUN*/
#ifdef DEBUG_BATCHFUN
#define DEBUG_95
#endif

#include <define.h>
#include <transact.h>
#include <tran.h>
#include <util.h>
#include <mem.h>
#include <gds.h>
#include <msg.h>
#include <msgfuncs.h>
#include <msgclrk.h>
#include <msgshf.h>
#include <udt.h>
#include <cdt.h>
#include <cst.h>
#include <hdt.h>
#include <bdt.h>
#include <opt.h>
#include <tct.h>
#include <trt.h>
#include <sdt.h>
#include <udt.h>
#include <confio.h>
#include <form.h>
#include <revutl.h>
#include <test.h>
#include <spdebug.h>
#include <ui.h>
#include <entry.h>
#include <operate.h>
#include <pbatch.h>
#include <mdlfuncs.h>
#include <accum.h>
#include <table.h>
#include <funcids.h>
#include <autosttl.h>
#include <settle.h>
#include <settlbat.h>
#include <review.h>
#include <batmsg.h>
#include <mht.h>
#include <pfr.h>
#include <codesec.h>
#include <logo.h>
#include <mit.h>
#include <merch.h>
#include <multilng.h>
#include <oper.h>
#include <date.h>
#include <tblutil.h>

#define BATCH_FNAME     "BAT"

/*********************************************************************************************
* @func static void | vdGetBatchFName |
*
*       Loads the corresponding batch file name based on the Merchant number
*           Eg.
*               "BATCH_FNAME" sufix + Merchant number
*
*           NB: Extension is put by the dbfm itself
*
* @parm char * | pchBFName |
*
* @rdesc VOID.
* @end
**********************************************************************************************/

void vdGetBatchFName(char* pchBFName) {
    /* This name attribution suggest a batch file per Merchant instead of per Host */

    /** /pdebug(("--vdGetBatchFName--"));*/
    sprintf(pchBFName, "%s%02d", BATCH_FNAME, inGetMerchantNum());
}

/*********************************************************************************************
* @func void | vdGetDupChkFName |
* Gets duplicate file name.
*
* @parm char * | pchFName |
*       Pointer to accumulator filename.
*
* @rdesc VOID
* @end
**********************************************************************************************/
void vdGetDupChkFName(char* pchFName) {
    /** /pdebug(("--vdGetDupChkFName--"));*/

    /* create dupchk based on merchant */
    sprintf(pchFName, "DUPCHK%02d.DAT", inGetMerchantNum());

    /** /pdebug(("pchFName = %s", pchFName));*/
}

/*********************************************************************************************
* @func int | inCompareFn |
*
*       DB_ Search function.
*
* @parm BATCH_KEY *     | psrBKey   |
* @parm BATCH_SKEY *    | MatchKey  |
*
* @rdesc Return values.
*
* @flag int     |   - VS_SUCCESS
*                   - VS_ERR
* @end
**********************************************************************************************/

int inCompareFn(BATCH_KEY* psrBKey,BATCH_SKEY* Matchstr) {
    int inRetVal;

    inRetVal = VS_SUCCESS;

    /** /pdebug (("--inCompareFn--%d",Matchstr->inKeyIdx));*/

    /* ALL Matches */
    if (Matchstr->inKeyIdx & KEY_ALL_RECS)
        return VS_SUCCESS;

    if (inRetVal == VS_SUCCESS) {
        /* Search on Invoice # */
        if (Matchstr->inKeyIdx & KEY_INV_NUM) {
            if (Matchstr->BKey.lnInvNum != psrBKey->lnInvNum) {
                /** /pdebug (("KEY_INV_NUM %ld/%ld",Matchstr->BKey.lnInvNum,psrBKey->lnInvNum));*/
                inRetVal = VS_ERR;
            }
        }
    }

    if (inRetVal == VS_SUCCESS) {
        /* Search on Shift */
        if (Matchstr->inKeyIdx & KEY_SHIFT) {
            if (Matchstr->BKey.chShift != psrBKey->chShift) {
                /** /pdebug (("KEY_SHIFT %c/%c",Matchstr->BKey.chShift,psrBKey->chShift));*/
                inRetVal = VS_ERR;
            }
        }
    }

    if (inRetVal == VS_SUCCESS) {
        /* Search on Account # Last 5 */
        if (Matchstr->inKeyIdx & KEY_ACC_NUM) {
            if (Matchstr->BKey.lnLast4 != psrBKey->lnLast4) {
                /** /pdebug (("KEY_ACC_NUM %ld/%ld",Matchstr->BKey.lnLast4,psrBKey->lnLast4));*/
                inRetVal = VS_ERR;
            }
        }
    }

    if (inRetVal == VS_SUCCESS) {
        /* Search on Clerk ID */
        if (Matchstr->inKeyIdx & KEY_SVR_ID) {
            if (strcmp(Matchstr->BKey.szClerkId, psrBKey->szClerkId) != 0) {
                /** /pdebug (("KEY_CLERK_ID %s/%s",Matchstr->BKey.szClerkId,psrBKey->szClerkId));*/
                inRetVal = VS_ERR;
            }
        }
    }

    if (inRetVal == VS_SUCCESS) {
        /* Search on Trans Amount */
        if (Matchstr->inKeyIdx & KEY_AMT) {
            if (Matchstr->BKey.lnTotalOfTransactionAmount != psrBKey->lnTotalOfTransactionAmount) {
                /** /pdebug (("KEY_AMT %ld/%ld",Matchstr->BKey.lnTotalOfTransactionAmount,psrBKey->lnTotalOfTransactionAmount));*/
                inRetVal = VS_ERR;
            }
        }
    }

    if (inRetVal == VS_SUCCESS) {
        /* Search on STAN # */
        if (Matchstr->inKeyIdx & KEY_ORG_STAN) {
            if (Matchstr->BKey.lnOrgSTAN != psrBKey->lnOrgSTAN) {
                /** /pdebug (("KEY_ORG_STAN %ld/%ld", Matchstr->BKey.lnOrgSTAN,psrBKey->lnOrgSTAN));*/
                inRetVal = VS_ERR;
            }
        }
    }

    if (inRetVal == VS_SUCCESS) {
        /* Search on Currency Index */
        if (Matchstr->inKeyIdx & KEY_CURRENCY) {
            if (Matchstr->BKey.inCurrencyIndex != psrBKey->inCurrencyIndex) {
                /** /pdebug (("KEY_CURRENCY %d/%d", Matchstr->BKey.inCurrencyIndex,psrBKey->inCurrencyIndex));*/
                inRetVal = VS_ERR;
            }
        }
    }

    if (inRetVal == VS_SUCCESS) {
        /* Search on HOST # */
        if (Matchstr->inKeyIdx & KEY_HOST) {
            if (Matchstr->BKey.inBatchHostIndex != psrBKey->inBatchHostIndex) {
                /** /pdebug (("KEY_HOST %d/%d",Matchstr->BKey.inBatchHostIndex,psrBKey->inBatchHostIndex));*/
                inRetVal = VS_ERR;
            }
        }
    }

    if (inRetVal == VS_SUCCESS) {
        /* Search on Last 5 digits of Account # */
        if (Matchstr->inKeyIdx & KEY_ACC_NUM) {
            if (Matchstr->BKey.lnLast4 != psrBKey->lnLast4) {
                /** /pdebug (("KEY_ACC_NUM %ld/%ld",Matchstr->BKey.lnLast4,psrBKey->lnLast4));*/
                inRetVal = VS_ERR;
            }
        }
    }

    if (inRetVal == VS_SUCCESS) {
        /* Search on Offline Flag */
        if (Matchstr->inKeyIdx & KEY_OFFLINE) {
            if (Matchstr->BKey.fOffline != psrBKey->fOffline)
                inRetVal = VS_ERR;
        }
    }

    if (inRetVal == VS_SUCCESS) {
        /* Search on Voided Flag */
        if (Matchstr->inKeyIdx & KEY_VOIDED) {
            if (Matchstr->BKey.fVoided != psrBKey->fVoided)
                inRetVal = VS_ERR;
        }
    }

    if (inRetVal == VS_SUCCESS) {
        /* Search on Uploaded Flag */
        if (Matchstr->inKeyIdx & KEY_UPLOADED) {
            if (Matchstr->BKey.fUploaded != psrBKey->fUploaded)
                inRetVal = VS_ERR;
        }
    }

    return(inRetVal);
} /* End of inCompareFn () */

/*********************************************************************************************
* @func int | inCheckForDuplicate |
*
*       Searches the open tab batch for invoice number and same host type
*       Searches the host batch for the same invoice number.
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc Return values.
*
* @flag int     |   - VS_SUCCESS
*                   - VS_ERR
* @end
**********************************************************************************************/

int inCheckForDuplicate(TRANSACTION_OBJECT* pobTran) {
    int inRetVal = VS_SUCCESS;
    long lnDBWhat = DB_FIRST;
    long lnRecNum;
    long lnResult;
    VS_BOOL fCloseOTBatch = VS_FALSE;
    VS_BOOL fCloseDCBatch = VS_FALSE;
    BATCH_KEY srBKey;
    BATCH_SKEY srBSKey;

    /*
     *      Save batch and CDT record, we will restore after search
     */

    /*
     *      Search Open Tab Batch: Open it if it is not already open
     */
    if (!pobTran->fOTBatchOpen) {
        fCloseOTBatch = VS_TRUE;
        vdBatchOTOpen(pobTran);
    }

    //Moved from above - before vdBatchOTOpen(), because in HH_CARD_OPERATION  PE606 CY1
    //GET_INV_NUM/inGetInvNum() call comes before OPEN_DC_BATCH, ie.,
    //compare_func is null, so db_seek_key fails (SYSTEM ERROR) on 2nd transaction,
    //why, I do not know
    srBSKey.compare_func = pobTran->srBSKey.compare_func;
    srBSKey.inKeyIdx = KEY_INV_NUM;
    srBSKey.BKey.lnInvNum = pobTran->srBKey.lnInvNum;

    lnResult = db_seek_key(&pobTran->dbOTBatch, &srBKey, &srBSKey, DB_FIRST, &lnRecNum);

    /*
     *      Close the Open Tab Batch if we had to open it.
     */
    if (fCloseOTBatch)
        vdCloseTabBatch(pobTran);

    /* DH1 - check the specified host batch for the same invoice number */
    if (!pobTran->fBatchOpen) {
        fCloseDCBatch = VS_TRUE;
        vdBatchDCOpen(pobTran);
    }

    //if comes before OPEN_DC_BATCH, ie., compare_func is null, db_seek_key  PE606  CY1
    //causes SYSTEM ERROR failure
    srBSKey.compare_func = pobTran->srBSKey.compare_func;
    srBSKey.BKey.lnInvNum = pobTran->srBKey.lnInvNum;

    if (lnResult == 0L) {
        /*
         *      Save current state of Tab Batch, force off to search regular batch.
         */
        lnResult = db_seek_key(&pobTran->dbBatch, &srBKey, &srBSKey, DB_FIRST, &lnRecNum);
        if (lnResult == 0L)
            inRetVal = VS_ERROR;
    }

    if (fCloseDCBatch)
        vdCloseDCBatch(pobTran);

    return(inRetVal); /* return of VS_SUCCESS means we have found a duplicate batch */
}

/*********************************************************************************************
* @func static int | inLoadCardCurrenyHostData |
*
*       Opens & loads Card Definition Table, the Currency Table and set the
*       language on swipe flag.
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc Return values.
*
* @flag int     |   - VS_SUCCESS
*                   - VS_ERR
* @end
**********************************************************************************************/

int inLoadCardCurrenyHostData(TRANSACTION_OBJECT* pobTran) {

    if (inGGCurCDTIndex() != NONCARD_HOST) {

        if (inLoadCDTRec(inGGCurCDTIndex()) != VS_SUCCESS) {

            vdDisplayMessageFromFile(CDT_ERR_MSG21, WARNING_MSG);
            return(VS_ERR);
        }
    }
    /* Load CST for batch record    */
    if (inLoadCSTRec(pobTran->srBKey.inCurrencyIndex) != VS_SUCCESS) {

        vdDisplayMessageFromFile(CST_ERR_MSG, WARNING_MSG);
        return(VS_ERR);
    }

    if (inLoadHostData(inGetHostHandle()) != VS_SUCCESS)
    	{
        return(VS_ERR);
    	}

    if (inLoadDefaultCurrency(pobTran) != VS_SUCCESS)
    	{
        return (VS_ERR);
    	}
    pobTran->fLanguageOnSwipe = VS_TRUE;

    return (VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inOpenBatch |
*
*       Opens/Creates the desired batch file.
*       The filename MUST NOT contain a file extension.
*
* @parm DB_FILE *   | psrDBFPtr |
* @parm char *  | pchFName |
*
* @rdesc Return values.
*
* @flag int    |    - VS_ERR
*                   - VS_SUCCESS
* @end
**********************************************************************************************/

int inOpenBatch(DB_FILE* psrDBFPtr,char* pchFName) {
    int inRetVal;
    /** /pdebug(("--inOpenBatch-%s-",pchFName));*/

    inRetVal = db_open(psrDBFPtr, pchFName, SIZE_BATCH_KEY, O_RDWR);

    if (inRetVal < 0) /* If file is non-existant, create it */
        inRetVal = db_open(psrDBFPtr, pchFName, SIZE_BATCH_KEY, (O_CREAT | O_RDWR));

    if (inRetVal < 0)
        return(VS_ERR);

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inCloseBatch |
*
*       Closes the batch file.
*       NOTE: Calling database manager opens 2 files.
*
* @parm DB_FILE *   | psrDBFPtr |
*
* @rdesc Return values.
*
* @flag int     |   - VS_SUCCESS
*                   - VS_ERR
* @end
**********************************************************************************************/

int inCloseBatch(DB_FILE* psrDBFPtr) {
    /** /pdebug(("--inCloseBatch--"));*/
    if (db_close(psrDBFPtr) > 0) {
        /** /pdebug(("--inCloseBatch--Success!"));*/
        return(VS_SUCCESS);
    }
    return(VS_ERR);
}

/*********************************************************************************************
* @func void | vdBatchDCOpen |
*
*       Open Data Capture batch.
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc VOID.
* @end
**********************************************************************************************/

void vdBatchDCOpen(TRANSACTION_OBJECT* pobTran) {
    inOpenDCBatch(pobTran);
}

/*********************************************************************************************
* @func void | vdCloseTabBatch |
*
*       This closes the Data Capture batch.
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc VOID
* @end
**********************************************************************************************/

void vdCloseDCBatch(TRANSACTION_OBJECT* pobTran) {
    inCloseDCBatch(pobTran);
} /* End of vdCloseDCBatch () */

/*********************************************************************************************
* @func int | inOpenDCBatch |
*
*       This opens the Data Capture batch, and loads the Search Key Compare Function.
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc Return values.
*
* @flag int     |   - VS_SUCCESS
*                   - VS_ERR
* @end
**********************************************************************************************/

int inOpenDCBatch(TRANSACTION_OBJECT* pobTran) {
    char szBatchFileName[FILENAME_SIZE + 1];


#ifdef IMAM_CLOSEBACTH
return (VS_SUCCESS);
    /** /pdebug (("--inOpenDCBatch--"));*/
#endif


    if (!pobTran->fBatchOpen) {
        vdGetBatchFName(szBatchFileName);
        /** /pdebug (("--inOpenDCBatch=%s",szBatchFileName));*/
        if (inOpenBatch(&pobTran->dbBatch, szBatchFileName) != VS_SUCCESS) {

            vdSGErrorMessage(BATCH_ERR_MSG);
            return(VS_ERR);
        }

        /*
         *      Load the batch compare function
           */
        pobTran->srBSKey.compare_func = inCompareFn;

        pobTran->fBatchOpen = VS_TRUE;
    }

    return (VS_SUCCESS);
}

/*********************************************************************************************
* @func int | insStoreBatchFieldData |
*
*       Store data to the batch flexi record
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       Transaction Object structure pointer
*
* @parm int | inFieldID |
*       Flexi Record Field ID
*
* @parm unsigned char * | pchData |
*       Buffer to store
*
* @parm int | inLength |
*       lentgh pchData buffer.
*
* @rdesc return values.
*
* @flag int    |  VS_ERR, VAR_INSUFFICIENT_BUFFER_SPACE, or VS_SUCCESS.
* @end
**********************************************************************************************/

int inStoreBatchFieldData(BATCH_REC* psrBRec,unsigned int uiFieldID,unsigned char* pchData,unsigned short shDataLength) {
    int inRetVal = VS_ERR;
    //jrd one source
    #ifdef __arm
    unsigned short    uiLength;
    #endif
    #ifdef _TARG_68000
    unsigned int    uiLength;
    #endif

    short shRetVal;
    unsigned char   ucType, ucAttributes;

    if ((shRetVal = shVarQueryField(psrBRec->pchHostData, uiFieldID, &uiLength, &ucType, &ucAttributes)) == VAR_NO_ERROR) {
        if ((shRetVal = shVarUpdateField(psrBRec->pchHostData, uiFieldID, pchData, shDataLength)) == VAR_NO_ERROR)
            inRetVal = VS_SUCCESS;
    } else if (shRetVal == VAR_FIELD_NOT_FOUND) {
        if ((shRetVal = shVarAddField(psrBRec->pchHostData, uiFieldID, pchData, shDataLength)) == VAR_NO_ERROR)
            inRetVal = VS_SUCCESS;
    }
    if (shRetVal == VAR_INSUFFICIENT_BUFFER_SPACE)
        inRetVal = (int) VAR_INSUFFICIENT_BUFFER_SPACE;

    return (inRetVal);
}

/*********************************************************************************************
* @func int | inGetBatchFieldData |
*
*       Retrieves data from the batch flexi record
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       Transaction Object structure pointer
*
* @parm int | inFieldID |
*       Flexi Record Field ID
*
* @parm unsigned char * | pchData |
*       Buffer to store data
*
* @parm int | inMaxLength |
*       Size of pchData buffer.
*
* @rdesc return values.
*
* @flag int     |   - >0, size of data retrieved
*                   - VS_ERR, ERROR (errno set to Flexi Record Error Value)
* @end
**********************************************************************************************/
extern int errno;

int inGetBatchFieldData(BATCH_REC* psrBRec,unsigned int uiFieldID,unsigned char* pchData,unsigned short shMaxLength) {
    int inRetVal = VS_ERROR;
    short shRetVal;
    #ifdef __arm
    unsigned short    uiLength;
    #endif
    #ifdef _TARG_68000
    unsigned int    uiLength;
    #endif

    if ((shRetVal = shVarGetField(psrBRec->pchHostData, uiFieldID, pchData, shMaxLength, &uiLength)) == VAR_NO_ERROR)
        inRetVal = (int) uiLength;
    else
        errno = (int) shRetVal;



    return inRetVal;
}

/*********************************************************************************************
* @func void | inCloseDCBatch |
*
*       This closes the Data Capture batch.
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/
int inCloseDCBatch(TRANSACTION_OBJECT* pobTran) {
    int inResult = VS_SUCCESS;

    if (pobTran->fBatchOpen) {
        if (inCloseBatch(&pobTran->dbBatch) != VS_SUCCESS) {

            vdSGErrorMessage(BATCH_ERR_MSG);
            inResult = VS_ERR;
        }
        pobTran->fBatchOpen = VS_FALSE;
    }

    return (inResult);
} /* End of vdCloseDCBatch () */

/*********************************************************************************************
* @func static int | inLoadCDTandCST |
*
*       Opens & loads Card Definition Table, the Currency Table and set the
*       language on swipe flag.
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc Return values.
*
* @flag int     |   - VS_SUCCESS
*                   - VS_ERR
* @end
**********************************************************************************************/
static int inLoadCDTandCST(TRANSACTION_OBJECT* pobTran) {
    if (inGGCurCDTIndex() != NONCARD_HOST) {
        if (inLoadCDTRec(inGGCurCDTIndex()) != VS_SUCCESS) {
            vdDisplayMessageFromFile(CDT_ERR_MSG21, WARNING_MSG);
            return(VS_ERR);
        }
    }
    /* Load CST for batch record    */
    if (inLoadCSTRec(pobTran->srBKey.inCurrencyIndex) != VS_SUCCESS) {
        vdDisplayMessageFromFile(CST_ERR_MSG, WARNING_MSG);
        return(VS_ERR);
    }

    pobTran->fLanguageOnSwipe = VS_TRUE;

    return (VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inLoadBatchRec |
*
*       Loads specific batch record from the Data Capture batch based on record
*       number.
*
* @parm TRANSACTION_OBJECT *    | pobTran |
* @parm int     | inRecNum |
*
* @rdesc Return values.
*
* @flag int     |   - VS_SUCCESS
*                   - VS_ERR
* @end
**********************************************************************************************/
int inLoadDCBatchRec(TRANSACTION_OBJECT* pobTran,int inRecNum) {
    VS_BOOL fSkipClose = VS_FALSE;

    /* Check if batch was open when we came in, in which case we
     * don't close it at the end
     */
    if (pobTran->fBatchOpen)
        fSkipClose = VS_TRUE;

    /* Open DC Batch */
    if (inOpenDCBatch(pobTran) != VS_SUCCESS)
        return(VS_ERR);

    if (inGetBatchRec(pobTran, inRecNum) != VS_SUCCESS)
        return(VS_ERR);

    if (inLoadCDTandCST(pobTran) != VS_SUCCESS)
        return(VS_ERR);

    pobTran->fLanguageOnSwipe = VS_TRUE;

    /* Close the DC Batch */
    if (!fSkipClose) {
        if (inCloseDCBatch(pobTran) != VS_SUCCESS)
            return(VS_ERR);
    }

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inAnyIndependentBatches |
*
*       Checks to see if any of the other hosts have independent
*       batches.
*
* @rdesc Return values.
*
* @flag int    |    - VS_TRUE
*                   - VS_ERR
* @end
**********************************************************************************************/

int inAnyIndependentBatches() {
    int inCount;
    int inNoHDTRecs;
    int inRetVal = VS_SUCCESS;
    unsigned char ucTempHDTRec[SIZE_HDT_REC + 1];
    //HDT_REC srTempHDTRec;

    /** /pdebug (("--inAnyIndependentBatches--"));*/

    inNoHDTRecs = inGetHDTTotRecs();

    for (inCount = 1; inCount < inNoHDTRecs; inCount++) {
        if (inLoadHDTRecFromStruct(inCount, ucTempHDTRec) != VS_SUCCESS) {
            vdDisplayMessageFromFile(HDT_ERR_MSG21, WARNING_MSG);
            inRetVal = VS_ERR;
            break;
        }
        if (fGetIndependentBatchFromStruct(ucTempHDTRec)) {
            inRetVal = VS_TRUE;
            break;
        }
    }

    return(inRetVal);
} /* End of inAnyIndependentBatches() */

/*********************************************************************************************
* @func VS_BOOL | fIsIndependentBatch |
*       Checks to see if specific host has an independent batch.
*
* @parm int     | inHostNum |
*
* @rdesc Return values.
* @flag int    |    - VS_TRUE
*                   - VS_FALSE
* @end
**********************************************************************************************/

VS_BOOL fIsIndependentBatch(int inHostNum) {
    VS_BOOL fRetVal = VS_FALSE;
    unsigned char ucTempHDTRec[SIZE_HDT_REC + 1];
    //HDT_REC srTempHDTRec;

    /** /pdebug (("--fIsIndependentBatch--"));*/
    if (inLoadHDTRecFromStruct(inHostNum, ucTempHDTRec) == VS_SUCCESS)
        fRetVal = fGetIndependentBatchFromStruct(ucTempHDTRec);

    return (fRetVal);
}

/*********************************************************************************************
* @func int | inWriteBatchData |
*
*       Form Batch data record for storage to batch.
*       Write Key and data to batch.
*
* @parm BATCH_KEY * | psrBKey |
*       Batch Key structure pointer
*
* @parm BATCH_REC * | psrBRec |
*       Batch Data structure pointer
*
* @parm DB_FILE * | psrDBF |
*       Data base file pointer
*
* @parm long | lnRecNum |
*       lnRecNum
*
* @rdesc return values.
*
* @flag int    |    - VS_ERR
*                   - Size of batch data record.
* @end
**********************************************************************************************/

int inWriteBatchData(DB_FILE* psrDBF,BATCH_KEY* psrBKey,BATCH_REC* psrBRec,long lnRecNum) {
    short shRet;
    int inRetVal = VS_SUCCESS;
    //jrd one source
    #ifdef __arm
    short inBatchRecFlexiSz,inHostDataFlexiSz;
    #endif
    #ifdef _TARG_68000
    int inBatchRecFlexiSz,inHostDataFlexiSz;
    #endif
    short //inHostDataFlexiSz,
    inBatchDataSz,
    //inBatchRecFlexiSz,

    inMaxBatchRecFlexiSz = (SIZE_OPTIONAL_BATCH_REC + sizeof(VAR_RECORD_HEADER) + (sizeof(VAR_RECORD_FIELD) * (NO_OPTIONAL_BATCH_FIELDS)));
    char* pchTempBatchData = NULL;
    unsigned char * pchTempMaxBatchRecFlexi;
    unsigned char * pchTempFlatBatchRecFlexi;
    unsigned char * pchTempHostDataFlexi;

    //pdebug (("--inWriteBatchData--"));

    /*
     *      Create temp batch rec flexi and move Batch Rec structure to flex
     *      Flatten batch rec flexi for storage.
     * /
        pdebug (("NO_OPTIONAL_BATCH_FIELDS=%d",NO_OPTIONAL_BATCH_FIELDS));
        pdebug (("SIZE_OPTIONAL_BATCH_REC=%d",SIZE_OPTIONAL_BATCH_REC));
        pdebug (("VAR_RECORD_HEADER=%d",sizeof(VAR_RECORD_HEADER)));
        pdebug (("VAR_RECORD_FIELD=%d",sizeof(VAR_RECORD_FIELD)));
        pdebug (("inMaxBatchRecFlexiSz=%d",inMaxBatchRecFlexiSz));
        */
    // Allocate space for maximum batch rec flexi



	    inRetVal = VS_SUCCESS;
    if ((pchTempMaxBatchRecFlexi = (unsigned char *) pchAlloc(inMaxBatchRecFlexiSz)) == NULL_CH) {

        vdSGErrorMessage(NO_MEM_ERR_MSG);
        inRetVal = VS_ERR;
    }

    if (inRetVal == VS_SUCCESS) {

        // Init maximum batch rec flexi
        vVarInitRecord(pchTempMaxBatchRecFlexi, inMaxBatchRecFlexiSz, 0);
        // Load maximum batch rec flexi from Batch Record
        if (inStoreOptionalBatchRecToFlexi(pchTempMaxBatchRecFlexi, psrBRec) != VS_SUCCESS) {
            pdebug(("ERROR->inStoreBatchRecToFlexi"));
            inRetVal = VS_ERR;
        }
    }

    if (inRetVal == VS_SUCCESS) {

        // Get actual length of maximum batch rec flexi
        if ((shRet = shGetRecordLength(pchTempMaxBatchRecFlexi, &inBatchRecFlexiSz)) != VAR_NO_ERROR) {
            pdebug(("ERROR->shGetRecordLength = %d", shRet));
            inRetVal = VS_ERR;
        }
    }

    if (inRetVal == VS_SUCCESS) {

        //pdebug (("pchAlloc(%d)",inBatchRecFlexiSz));
        // Allocate space for actual size of batch rec flex
        if ((pchTempFlatBatchRecFlexi = (unsigned char *) pchAlloc(inBatchRecFlexiSz)) == NULL_CH) {
            vdSGErrorMessage(NO_MEM_ERR_MSG);
            inRetVal = VS_ERR;
        }
    }

    if (inRetVal == VS_SUCCESS) {

        // Init batch rec flexi
        vVarInitRecord(pchTempFlatBatchRecFlexi, inBatchRecFlexiSz, 0);
        // Flatten maximum batch rec flexi to actual size batch rec flexi for storage
        if ((shRet = shVarFlatten(pchTempMaxBatchRecFlexi, (unsigned char *) pchTempFlatBatchRecFlexi)) != VAR_NO_ERROR) {
            vdSGErrorMessage(NO_MEM_ERR_MSG);
            inRetVal = VS_ERR;
        }
        vdFree((char *) pchTempMaxBatchRecFlexi);
    }

    if (inRetVal == VS_SUCCESS) {

        // Get length of current host data flexi record.
        if ((shRet = shGetRecordLength(psrBRec->pchHostData, &inHostDataFlexiSz)) != VAR_NO_ERROR) {
            //pdebug(("psrBRec->pchHostData   = %lX", psrBRec->pchHostData));
            pdebug(("ERROR->shGetRecordLength = %d", shRet));
            inRetVal = VS_ERR;
        }
    }

    /*
     *      Allocate space for, and get flattened batch record & replace
     *      current host data flexi record with flattened version.
     */
    if (inRetVal == VS_SUCCESS) {

        //pdebug (("inHostDataFlexiSz=%d",inHostDataFlexiSz));
        //pdebug (("SIZE_BATCH_REC=%d",SIZE_BATCH_REC));
        //pdebug (("inBatchDataSz=%d",inBatchDataSz));
        //pdebug (("pchAlloc(%d)",inHostDataFlexiSz));
        // Allocate space for actual size host data flexi
        if ((pchTempHostDataFlexi = (unsigned char *) pchAlloc(inHostDataFlexiSz)) == NULL_CH) {
            vdSGErrorMessage(NO_MEM_ERR_MSG);
            inRetVal = VS_ERR;
        }
    }

    if (inRetVal == VS_SUCCESS) {

        // Init actual size host data flexi
        vVarInitRecord(pchTempHostDataFlexi, inHostDataFlexiSz, 0);
        // Flatten host data flexi to actual size host data flexi
        if ((shRet = shVarFlatten(psrBRec->pchHostData, (unsigned char *) pchTempHostDataFlexi)) != VAR_NO_ERROR) {
            vdSGErrorMessage(NO_MEM_ERR_MSG);
            inRetVal = VS_ERR;
        }
    }

    if (inRetVal == VS_SUCCESS) {

        // Commented this code, so that the original host flexi record
        // remains as a 500 byte buffer for addition of fields in functions
        // such as VITL_COMMERCIAL_CARD for tax.
        // Update host data flexi pointer
        //vdFree ((char *)psrBRec->pchHostData);
        //psrBRec->pchHostData = pchTempHostDataFlexi;

        // Allocate space for fixed and flexi portion of batch data and put them together.
        inBatchDataSz = SIZE_BATCH_DATA + inBatchRecFlexiSz + inHostDataFlexiSz;
        //pdebug (("pchAlloc(%d)",inBatchDataSz));
        if ((pchTempBatchData = pchAlloc(inBatchDataSz)) == NULL_CH) {
            vdSGErrorMessage(NO_MEM_ERR_MSG);
            inRetVal = VS_ERR;
        }
    }

    if (inRetVal == VS_SUCCESS) {

        memcpy(pchTempBatchData, psrBRec, SIZE_BATCH_DATA);
        memcpy(pchTempBatchData + SIZE_BATCH_DATA, pchTempFlatBatchRecFlexi, inBatchRecFlexiSz);
        memcpy(pchTempBatchData + SIZE_BATCH_DATA + inBatchRecFlexiSz, pchTempHostDataFlexi, inHostDataFlexiSz);

        // Write batch data and and free batch data record.
        if ((shRet = db_write(psrDBF, psrBKey, pchTempBatchData, (unsigned) inBatchDataSz, lnRecNum)) < 0) {

            vdSGErrorMessage(BATCH_ERR_MSG);
            inRetVal = VS_ERR;
        }
    }

    if (pchTempBatchData != NULL) {

        //pdebug(("vdFree (%lX)", pchTempBatchData));
        vdFree(pchTempBatchData);
    }

    if (pchTempFlatBatchRecFlexi != NULL) {

        //pdebug(("vdFree (%lX)", pchTempFlatBatchRecFlexi));
        vdFree((char *) pchTempFlatBatchRecFlexi);
    }

    if (pchTempHostDataFlexi != NULL) {

        //pdebug(("vdFree (%lX)", pchTempHostDataFlexi));
        vdFree((char *) pchTempHostDataFlexi);
    }



    if (inRetVal == VS_SUCCESS) {

        // Update Batch Rec Size in .BDI file
        if (inSetMaxBatchRecSize(inBatchDataSz) != VS_SUCCESS) {

            vdSGErrorMessage(BATCH_ERR_MSG);
            return(VS_ERR);
        }
    }

    return (inRetVal);
}

int inOldWriteBatchData(DB_FILE* psrDBF,BATCH_KEY* psrBKey,BATCH_REC* psrBRec,long lnRecNum) {
    short shRet;
    int inRetVal = VS_SUCCESS;
    //jrd one source
    #ifdef __arm
    short inFlexiRecSz;
    #endif
    #ifdef _TARG_68000
    int inFlexiRecSz;
    #endif
    short //inFlexiRecSz,
    inBatchDataSz;
    char* pchTempBatchData = NULL;
    unsigned char * pchTempFlexiRec;

    //pdebug (("--inWriteBatchData--"));
    /*
     *      Get length of current batch flexi record.
     */
    if ((shRet = shGetRecordLength(psrBRec->pchHostData, &inFlexiRecSz)) != VAR_NO_ERROR) {
        //pdebug(("psrBRec->pchHostData   = %lX", psrBRec->pchHostData));
        pdebug(("ERROR->shGetRecordLength = %d", shRet));
        inRetVal = VS_ERR;
    }

    if (inRetVal == VS_SUCCESS) {
        inBatchDataSz = SIZE_BATCH_REC + inFlexiRecSz;
        //pdebug (("inFlexiRecSz=%d",inFlexiRecSz));
        //pdebug (("SIZE_BATCH_REC=%d",SIZE_BATCH_REC));
        //pdebug (("inBatchDataSz=%d",inBatchDataSz));

        /*
         *      Allocate space for, and get flattened batch record & replace
           *      current batch flexi record with flattened version.
         */
        //pdebug (("pchAlloc(%d)",inFlexiRecSz));
        if ((pchTempFlexiRec = (unsigned char *) pchAlloc(inFlexiRecSz)) == NULL_CH) {
            vdSGErrorMessage(NO_MEM_ERR_MSG);
            inRetVal = VS_ERR;
        }
    }

    if (inRetVal == VS_SUCCESS) {
        vVarInitRecord(pchTempFlexiRec, inFlexiRecSz, 0);
        if ((shRet = shVarFlatten(psrBRec->pchHostData, (unsigned char *) pchTempFlexiRec)) != VAR_NO_ERROR) {
            vdSGErrorMessage(NO_MEM_ERR_MSG);
            inRetVal = VS_ERR;
        }
    }

    if (inRetVal == VS_SUCCESS) {
        vdFree((char *) psrBRec->pchHostData);
        psrBRec->pchHostData = pchTempFlexiRec;

        /*
         *      Allocate space for fixed and flexi portion of batch data and put them together.
           */
        //pdebug (("pchAlloc(%d)",inBatchDataSz));
        if ((pchTempBatchData = pchAlloc(inBatchDataSz)) == NULL_CH) {
            vdSGErrorMessage(NO_MEM_ERR_MSG);
            inRetVal = VS_ERR;
        }
    }

    if (inRetVal == VS_SUCCESS) {
        memcpy(pchTempBatchData, psrBRec, SIZE_BATCH_REC);
        memcpy(pchTempBatchData + SIZE_BATCH_REC, psrBRec->pchHostData, inFlexiRecSz);

        /*
         *      Write batch data and and free batch data record.
           */
        if ((shRet = db_write(psrDBF, psrBKey, pchTempBatchData, (unsigned) inBatchDataSz, lnRecNum)) < 0) {

            vdSGErrorMessage(BATCH_ERR_MSG);
            inRetVal = VS_ERR;
        }
    }

    if (pchTempBatchData != NULL) {
        //pdebug(("vdFree (%lX)", pchTempBatchData));
        vdFree(pchTempBatchData);
    }

    if (inRetVal == VS_SUCCESS) {
        /* Update Batch Rec Size in .BDI file */
        if (inSetMaxBatchRecSize(inBatchDataSz) != VS_SUCCESS) {

            vdSGErrorMessage(BATCH_ERR_MSG);
            return(VS_ERR);
        }
    }

    return (inRetVal);
}


/*********************************************************************************************
* @func int | inReadBatchData |
*
*       Read Batch data record from batch.
*       Extract data to Batch structure and flexi record.
*
* @parm BATCH_KEY * | psrBKey |
*       Batch Key structure pointer
*
* @parm BATCH_REC * | psrBRec |
*       Batch Data structure pointer
*
* @parm DB_FILE * | psrDBF |
*       Data base file pointer
*
* @parm long | lnRecNum |
*       lnRecNum
*
* @rdesc return values.
*
* @flag int    |    - VS_ERR
*                   - Size of batch data record.
* @end
**********************************************************************************************/
int inReadBatchData(DB_FILE* psrDBF,BATCH_KEY* psrBKey,BATCH_REC* psrBRec,long lnRecNum) {
    int inRetVal = VS_SUCCESS;
    short shMaxBatchDataSz;
    //jrd one source
    #ifdef __arm
    short shBatchRecFlexiSz;
    #endif
    #ifdef _TARG_68000
    int shBatchRecFlexiSz;
    #endif

    short shRet;
    unsigned char * pchTempBatchData;

    //pdebug (("--inReadBatchData--"));

    // Get maximum length of current batch flexi record.
    shMaxBatchDataSz = inGetMaxBatchRecSize();
    if (shMaxBatchDataSz <= 0) /* 0 or VS_ERR */
        inRetVal = VS_ERR;

    // Allocate space for fixed and flexi portion of batch data.
    if ((pchTempBatchData = (unsigned char *) pchAlloc(shMaxBatchDataSz)) == NULL_CH)
        inRetVal = VS_ERR;

    // Read batch record
    if (inRetVal == VS_SUCCESS) {
        if (db_read(psrDBF, psrBKey, (char *) pchTempBatchData, shMaxBatchDataSz, lnRecNum) < 0)
            inRetVal = VS_ERR;
        else {
            //Free current batch flexi record
            vdFree((char *) psrBRec->pchHostData);
        }
    }

    // move batch data structure
    if (inRetVal == VS_SUCCESS) {
        memcpy(psrBRec, pchTempBatchData, SIZE_BATCH_DATA);
        if (inLoadOptionalBatchRecFromFlexi(pchTempBatchData + SIZE_BATCH_DATA, psrBRec) != VS_SUCCESS)
            inRetVal = VS_ERR;
    }

    // Copy new batch flexi record
    if (inRetVal == VS_SUCCESS) {
        if ((psrBRec->pchHostData = (unsigned char *) pchAlloc(MAX_HOST_DATA_FLEXI_SZ)) == NULL_CH)
            inRetVal = VS_ERR;
        else {
            if ((shRet = shGetRecordLength(pchTempBatchData + SIZE_BATCH_DATA, &shBatchRecFlexiSz)) != VAR_NO_ERROR)
                inRetVal = VS_ERR;
            else {
                vVarInitRecord(psrBRec->pchHostData, MAX_HOST_DATA_FLEXI_SZ, 0);
                if ((shRet = shVarFlatten(pchTempBatchData + SIZE_BATCH_DATA + shBatchRecFlexiSz, psrBRec->pchHostData)) != VAR_NO_ERROR)
                    inRetVal = VS_ERR;
            }
        }
    }

    if (pchTempBatchData != NULL) {
        //pdebug(("vdFree (%lX)", pchTempBatchData));
        vdFree((char *) pchTempBatchData);
    }

    if (inRetVal != VS_SUCCESS)
    {

        vdSGErrorMessage(BATCH_ERR_MSG);
	}
    return  inRetVal;
}

int inOldReadBatchData(DB_FILE* psrDBF,BATCH_KEY* psrBKey,BATCH_REC* psrBRec,long lnRecNum) {
    int     inRetVal = VS_SUCCESS,
    inMaxBatchDataSz;
    short shRet;
    unsigned char * pchTempBatchData;

    /*
     *      Get maximum length of current batch flexi record.
     */
    inMaxBatchDataSz = inGetMaxBatchRecSize();
    if (inMaxBatchDataSz <= 0) /* 0 or VS_ERR */
        inRetVal = VS_ERR;

    /*
     *      Allocate space for fixed and flexi portion of batch data.
     */
    if ((pchTempBatchData = (unsigned char *) pchAlloc(inMaxBatchDataSz)) == NULL_CH)
        inRetVal = VS_ERR;

    /*
     *      Read batch record and
     *      move batch structure data.
     */
    if (inRetVal == VS_SUCCESS) {
        if (db_read(psrDBF, psrBKey, (char *) pchTempBatchData, inMaxBatchDataSz, lnRecNum) < 0)
            inRetVal = VS_ERR;
        else {
            vdFree((char *) psrBRec->pchHostData);
            memcpy(psrBRec, pchTempBatchData, SIZE_BATCH_REC);
        }
    }

    /*
     *      Free current batch flexi record, copy new batch flexi record
     */
    if (inRetVal == VS_SUCCESS) {
        if ((psrBRec->pchHostData = (unsigned char *) pchAlloc(MAX_HOST_DATA_FLEXI_SZ)) == NULL_CH)
            inRetVal = VS_ERR;
        else {
            vVarInitRecord(psrBRec->pchHostData, MAX_HOST_DATA_FLEXI_SZ, 0);
            if ((shRet = shVarFlatten(pchTempBatchData + SIZE_BATCH_REC, psrBRec->pchHostData)) != VAR_NO_ERROR)
                inRetVal = VS_ERR;
        }
    }

    vdFree((char *) pchTempBatchData);
    if (inRetVal != VS_SUCCESS)
    {

        vdSGErrorMessage(BATCH_ERR_MSG);
	}
    return  inRetVal;
}


/*********************************************************************************************
* @func int | inGetMaxBatchRecSize |
*
*       Returns current max batch flexi record size from data file.
*
* @parm VOID
*
* @rdesc
*
* @flag int    |    - max batch flexi record size
* @end
**********************************************************************************************/

static int inGetMaxBatchRecSize(void) {
    BATCH_DATA_INFO srBDI;

    //pdebug (("inGetMaxBatchRecSize=%d",srBDI.inMaxRecSize));
    /* Clear buffer */
    memset((char *) &srBDI, 0x00, sizeof(BATCH_DATA_INFO));

    if (inGetBatchDataInfo((char *) &srBDI) != VS_SUCCESS)
        return(VS_ERR);
    return (srBDI.inMaxRecSize);
}

/*********************************************************************************************
* @func void | inSetMaxBatchRecSize |
*
*       Update current max batch flexi record size tp data file.
*
* @parm VOID
*
* @rdesc
*
* @flag int    |    - max batch flexi record size
* @end
**********************************************************************************************/

static int inSetMaxBatchRecSize(int inRecSize) {
    BATCH_DATA_INFO srBDI;

    //pdebug (("inSetMaxBatchRecSize=%d",inRecSize));

    /* Clear buffer */
    memset((char *) &srBDI, 0x00, sizeof(BATCH_DATA_INFO));

    if (inGetBatchDataInfo((char *) &srBDI) != VS_SUCCESS)
        return(VS_ERR);

    if (inRecSize > srBDI.inMaxRecSize) {
        srBDI.inMaxRecSize = inRecSize;
        pdebug(("Update MaxBatchRecSize=%d", srBDI.inMaxRecSize));
        if (inSetBatchDataInfo((char *) &srBDI) != VS_SUCCESS)
            return (VS_ERR);
    }

    return (VS_SUCCESS);
}

/*********************************************************************************************
* @func void | vdResetMaxBatchRecSize |
*
*       Clears Max Bax Record Size data file.
*
* @parm VOID
*
* @rdesc VOID
*
* @end
**********************************************************************************************/

void vdResetMaxBatchRecSize(void) {
    char szFilename[FILENAME_SIZE + 1];

    vdGetBatchFName(szFilename);
    strcat(szFilename, ".BDI");
    remove(szFilename);
    /** /pdebug (("vdResetMaxBatchRecSize=%s",szFilename));*/
}

static int inGetBatchDataInfo(char* pchData) {
    int hBDIFile,
    inResult;
    char szFilename[FILENAME_SIZE + 1];


    vdGetBatchFName(szFilename);
    strcat(szFilename, ".BDI");

    /** /pdebug (("vdGetBatchDataInfo=%s",szFilename));*/

    memset(pchData, 0, sizeof(BATCH_DATA_INFO));
    if ((hBDIFile = open(szFilename, O_RDONLY)) > 0) {
        if ((inResult = read(hBDIFile, pchData, sizeof(BATCH_DATA_INFO))) < sizeof(BATCH_DATA_INFO)) {
            extern int errno;
            //pdebug (("vdGetBatchDataInfo=%d/%d",inResult,errno));
            close(hBDIFile);
            return(VS_ERR);
        }
        close(hBDIFile);
    } else {
        extern int errno;
        //pdebug (("vdGetBatchDataInfo=%d/%d",hBDIFile,errno));
    }

    return(VS_SUCCESS);
}

static int inSetBatchDataInfo(char* pchData) {
    int hBDIFile,
    inResult;
    char szFilename[FILENAME_SIZE + 1];

    vdGetBatchFName(szFilename);
    strcat(szFilename, ".BDI");
    /** /pdebug (("vdSetBatchDataInfo=%s",szFilename));*/
    /* Recreate the BDI file */
    if ((hBDIFile = open(szFilename, O_CREAT | O_TRUNC | O_RDWR)) > 0) {
        /* Store the BDI data */
        if ((inResult = write(hBDIFile, pchData, sizeof(BATCH_DATA_INFO))) < sizeof(BATCH_DATA_INFO)) {
            extern int errno;
            //pdebug (("vdSetBatchDataInfo=%d/%d",inResult,errno));
            close(hBDIFile);
            return(VS_ERR);
        }
        close(hBDIFile);
    } else {
        extern int errno;
        //pdebug (("vdSetBatchDataInfo=%d/%d",hBDIFile,errno));
        return(VS_ERR);
    }

    return(VS_SUCCESS);
}

int BATCHFUN_CODE_CHECK(char* a,char* b,short * c,char* d,unsigned char* e) {
    GET_VER(a, b, c, d, e);
    return 1;
}

#undef BATCHFUN_C

#endif // BATCH_DEFINED
